<?php

/**
 * Created By PhpStorm
 * User sclecon
 * Contact Email 27941662@qq.com
 * Time 2021/10/21 14:49
 */


namespace wowo;



class Middleware
{
    protected $configRule = [];
    protected $resolve = [];

    public function __construct()
    {
        $this->load();
        $this->screen();
    }

    private function load(){
        $configFile = app()->appPath.app()->directory.'app'.app()->directory.'middleware.php';
        if (file_exists($configFile)){
            $this->configRule = include $configFile;
        }
    }

    private function screen(){
        $object = \wowo\instance\Request::getObject();
        foreach ($this->configRule as $item){
            $middleware = false;
            if (is_string($item)){
                $middleware = $item;
            } else if (is_array($item) and isset($item['middleware']) and (isset($item['allow']) or isset($item['ignore']))){
                if (in_array($object, $item['allow'])){
                    $middleware = $item['middleware'];
                } else if (in_array($object, $item['ignore']) === false){
                    $middleware = $item['middleware'];
                }
            }
            if ($middleware and class_exists($middleware) and method_exists($middleware, 'handle')){
                $this->resolve[] = $middleware;
            }
        }
    }

    public function dispatch(){
        $request = \wowo\instance\Request::getInstance();
        return call_user_func($this->resolve(), $request);
    }

    protected function resolve(){
        return function($request){
            $middleware = array_shift($this->resolve);
            if ($middleware){
                return call_user_func_array([$middleware, 'handle'], [$request, $this->resolve()]);
            }
            $object = $request->getObject();
            $action = $request->getAction();
            return call_user_func_array([Container::get($object), $action], Container::getInstance()->invokeArgs($object, $action, []));
        };
    }
}